package static

import (
	"errors"
	"io/fs"
	"os"
	"path/filepath"
	"regexp"

	"gopkg.in/yaml.v3"
)

// AnalyzeStatic scans projectDir and returns paths to configuration and template files.
// It also writes the result to analysis_result.yaml under projectDir.
func AnalyzeStatic(projectDir string) ([]string, error) {
	if projectDir == "" {
		return nil, errors.New("projectDir is empty")
	}

	resultSet := make(map[string]struct{})

	// Regex to find config and template paths in Go files
	re := regexp.MustCompile(`"([^"]+\.(?:ya?ml|json|conf|ini|cfg))"|"([^"]*templates/[^"]*)"`)

	err := filepath.WalkDir(projectDir, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			if d.Name() == "templates" {
				resultSet[path] = struct{}{}
			}
			return nil
		}

		ext := filepath.Ext(path)
		switch ext {
		case ".yaml", ".yml", ".json", ".conf", ".ini", ".cfg":
			resultSet[path] = struct{}{}
		case ".go":
			data, err := os.ReadFile(path)
			if err != nil {
				return err
			}
			matches := re.FindAllStringSubmatch(string(data), -1)
			for _, m := range matches {
				for i := 1; i < len(m); i++ {
					if m[i] != "" {
						resultSet[m[i]] = struct{}{}
					}
				}
			}
		}
		return nil
	})
	if err != nil {
		return nil, err
	}

	var results []string
	for p := range resultSet {
		results = append(results, p)
	}

	out := struct {
		Files []string `yaml:"files"`
	}{Files: results}

	data, err := yaml.Marshal(out)
	if err != nil {
		return nil, err
	}

	if err := os.WriteFile(filepath.Join(projectDir, "analysis_result.yaml"), data, 0644); err != nil {
		return nil, err
	}

	return results, nil
}
